Skip to contentMethod: static {...}
1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.owlapi;
16:
17: import cz.cvut.kbss.ontodriver.descriptor.*;
18: import cz.cvut.kbss.ontodriver.model.Axiom;
19: import cz.cvut.kbss.ontodriver.owlapi.connector.Connector;
20: import cz.cvut.kbss.ontodriver.owlapi.connector.OntologySnapshot;
21: import cz.cvut.kbss.ontodriver.owlapi.exception.OwlapiDriverException;
22: import cz.cvut.kbss.ontodriver.owlapi.list.ListHandler;
23: import cz.cvut.kbss.ontodriver.owlapi.query.OwlapiPreparedStatement;
24: import cz.cvut.kbss.ontodriver.owlapi.query.OwlapiStatement;
25: import cz.cvut.kbss.ontodriver.owlapi.query.StatementExecutorFactory;
26: import cz.cvut.kbss.ontodriver.owlapi.util.IdentifierGenerator;
27: import org.semanticweb.owlapi.model.OWLAxiom;
28: import org.semanticweb.owlapi.model.OWLDataFactory;
29: import org.semanticweb.owlapi.model.OWLOntology;
30: import org.semanticweb.owlapi.model.OWLOntologyChange;
31: import org.semanticweb.owlapi.reasoner.OWLReasoner;
32:
33: import java.net.URI;
34: import java.util.*;
35:
36: /**
37: * Adapter between OntoDriver API and OWLAPI.
38: */
39: public class OwlapiAdapter {
40:
41: private final Connector connector;
42: private OntologySnapshot ontologySnapshot;
43:
44: private StatementExecutorFactory statementExecutorFactory;
45:
46: private TransactionState transactionState = TransactionState.INITIAL;
47: private List<OWLOntologyChange> pendingChanges = new ArrayList<>();
48:
49: private enum TransactionState {
50: INITIAL, RUNNING
51: }
52:
53: public OwlapiAdapter(Connector connector) {
54: this.connector = connector;
55: }
56:
57: private void startTransactionIfNotActive() {
58: if (transactionState == TransactionState.INITIAL) {
59: this.ontologySnapshot = connector.getOntologySnapshot();
60: this.transactionState = TransactionState.RUNNING;
61: this.statementExecutorFactory = new StatementExecutorFactory(ontologySnapshot, connector);
62: }
63: }
64:
65: void commit() {
66: if (transactionState != TransactionState.RUNNING) {
67: return;
68: }
69: if (!pendingChanges.isEmpty()) {
70: connector.applyChanges(pendingChanges);
71: this.pendingChanges = new ArrayList<>();
72: }
73: transactionCleanup();
74: }
75:
76: private void transactionCleanup() {
77: connector.closeSnapshot(ontologySnapshot);
78: this.ontologySnapshot = null;
79: this.transactionState = TransactionState.INITIAL;
80: }
81:
82: void rollback() {
83: if (transactionState != TransactionState.RUNNING) {
84: return;
85: }
86: if (!pendingChanges.isEmpty()) {
87: pendingChanges = new ArrayList<>();
88: }
89: transactionCleanup();
90: }
91:
92: boolean isConsistent(URI context) {
93: startTransactionIfNotActive();
94:
95: return ontologySnapshot.getReasoner().isConsistent();
96: }
97:
98: private OWLReasoner reasoner() {
99: return ontologySnapshot.getReasoner();
100: }
101:
102: private OWLOntology ontology() {
103: return ontologySnapshot.getOntology();
104: }
105:
106: private OWLDataFactory dataFactory() {
107: return ontologySnapshot.getDataFactory();
108: }
109:
110: List<URI> getContexts() {
111: startTransactionIfNotActive();
112: return Collections.singletonList(connector.getOntologyUri());
113: }
114:
115: boolean containsAxiom(Axiom<?> axiom, Set<URI> contexts) {
116: startTransactionIfNotActive();
117: final Collection<OWLAxiom> owlAxiom = asOwlAxioms(axiom);
118: boolean contains;
119: for (OWLAxiom ax : owlAxiom) {
120: if (axiom.getAssertion().isInferred()) {
121: contains = reasoner().isEntailed(ax);
122: } else {
123: contains = ontology().containsAxiom(ax);
124: }
125: if (contains) {
126: return true;
127: }
128: }
129: return false;
130: }
131:
132: private Collection<OWLAxiom> asOwlAxioms(Axiom<?> axiom) {
133: final Collection<OWLAxiom> owlAxioms = new ArrayList<>(3);
134: final AxiomAdapter axiomAdapter = new AxiomAdapter(dataFactory());
135: switch (axiom.getAssertion().getType()) {
136: case CLASS:
137: owlAxioms.add(axiomAdapter.toOwlClassAssertionAxiom(axiom));
138: break;
139: case OBJECT_PROPERTY:
140: owlAxioms.add(axiomAdapter.toOwlObjectPropertyAssertionAxiom(axiom));
141: break;
142: case DATA_PROPERTY:
143: owlAxioms.add(axiomAdapter.toOwlDataPropertyAssertionAxiom(axiom));
144: break;
145: case ANNOTATION_PROPERTY:
146: owlAxioms.add(axiomAdapter.toOwlAnnotationPropertyAssertionAxiom(axiom));
147: break;
148: default:
149: owlAxioms.add(axiomAdapter.toOwlClassAssertionAxiom(axiom));
150: owlAxioms.add(axiomAdapter.toOwlObjectPropertyAssertionAxiom(axiom));
151: owlAxioms.add(axiomAdapter.toOwlDataPropertyAssertionAxiom(axiom));
152: owlAxioms.add(axiomAdapter.toOwlAnnotationPropertyAssertionAxiom(axiom));
153: break;
154: }
155: return owlAxioms;
156: }
157:
158: Collection<Axiom<?>> find(AxiomDescriptor descriptor) {
159: startTransactionIfNotActive();
160: return new MainAxiomLoader(this, ontologySnapshot).findAxioms(descriptor);
161: }
162:
163: void persist(AxiomValueDescriptor descriptor) {
164: startTransactionIfNotActive();
165: new AxiomSaver(this, ontologySnapshot).persist(descriptor);
166: }
167:
168: URI generateIdentifier(URI classUri) {
169: startTransactionIfNotActive();
170: return new IdentifierGenerator(ontology()).generateIdentifier(classUri);
171: }
172:
173: void update(AxiomValueDescriptor descriptor) {
174: startTransactionIfNotActive();
175: new EpistemicAxiomRemover(this, ontologySnapshot).remove(descriptor);
176: new AxiomSaver(this, ontologySnapshot).persist(descriptor);
177: }
178:
179: void remove(AxiomDescriptor descriptor) {
180: startTransactionIfNotActive();
181: new EpistemicAxiomRemover(this, ontologySnapshot).remove(descriptor);
182: }
183:
184: TypesHandler getTypesHandler() {
185: startTransactionIfNotActive();
186: return new TypesHandler(this, ontologySnapshot);
187: }
188:
189: PropertiesHandler getPropertiesHandler() {
190: startTransactionIfNotActive();
191: return new PropertiesHandler(this, ontologySnapshot);
192: }
193:
194: public void addTransactionalChanges(Collection<OWLOntologyChange> changes) {
195: pendingChanges.addAll(changes);
196: }
197:
198: public ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> getSimpleListHandler() {
199: startTransactionIfNotActive();
200: return ListHandler.getSimpleListHandler(this, ontologySnapshot);
201: }
202:
203: public ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> getReferencedListHandler() {
204: startTransactionIfNotActive();
205: return ListHandler.getReferencedListHandler(this, ontologySnapshot);
206: }
207:
208: public OwlapiStatement createStatement(OwlapiConnection connection) {
209: startTransactionIfNotActive();
210: return new OwlapiStatement(statementExecutorFactory, connection);
211: }
212:
213: public OwlapiPreparedStatement prepareStatement(String statement, OwlapiConnection connection) {
214: startTransactionIfNotActive();
215: return new OwlapiPreparedStatement(statementExecutorFactory, connection, statement);
216: }
217:
218: public <T> T unwrap(Class<T> cls) throws OwlapiDriverException {
219: startTransactionIfNotActive();
220: if (cls.isAssignableFrom(this.getClass())) {
221: return cls.cast(this);
222: } else if (cls.isAssignableFrom(OWLOntology.class)) {
223: return cls.cast(ontologySnapshot.getOntology());
224: } else if (cls.isAssignableFrom(OWLReasoner.class)) {
225: return cls.cast(ontologySnapshot.getReasoner());
226: }
227: throw new OwlapiDriverException("Unsupported type " + cls);
228: }
229: }